package com.dnjn.happiness.emo.service.impl;


import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dnjn.happiness.common.core.constant.Constants;
import com.dnjn.happiness.common.core.constant.HappyConstants;
import com.dnjn.happiness.common.core.constant.SecurityConstants;
import com.dnjn.happiness.common.core.domain.R;
import com.dnjn.happiness.common.core.utils.StringUtils;
import com.dnjn.happiness.common.core.utils.bean.BeanUtils;
import com.dnjn.happiness.emo.api.RemoteRiskService;

import com.dnjn.happiness.emo.api.model.RiskVO;
import com.dnjn.happiness.emo.config.HappyCoefficientConfig;
import com.dnjn.happiness.emo.domain.EmoHscoreLog;
import com.dnjn.happiness.emo.api.domain.UserModelScore;

import com.dnjn.happiness.emo.domain.User;
import com.dnjn.happiness.emo.domain.vo.UserModelScoreVO;
import com.dnjn.happiness.emo.mapper.UserModelScoreMapper;
import com.dnjn.happiness.emo.service.IEmoHscoreLogService;
import com.dnjn.happiness.emo.service.IUserModelScoreService;
import com.dnjn.happiness.emo.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * userModelScoreService业务层处理
 *
 * @author amber
 * @date 2024-03-02
 */
@Service
public class UserModelScoreServiceImpl extends ServiceImpl<UserModelScoreMapper, UserModelScore> implements IUserModelScoreService {

    @Autowired
    private HappyCoefficientConfig config;

    @Autowired
    private IEmoHscoreLogService emoHscoreLogService;

    @Autowired
    private RemoteRiskService riskService;

    @Autowired
    private IUserService emoUserService;

    @Override
    public void updateUserModelScore(UserModelScoreVO domain) {
        UserModelScore userModelScore = new UserModelScore();
        BeanUtils.copyProperties(domain, userModelScore);
        userModelScore.setBaseScore(BigDecimal.valueOf(domain.getBaseScore()));
        userModelScore.setRecordScore(BigDecimal.valueOf(domain.getRecordScore()));
        userModelScore.setTotalScore(BigDecimal.valueOf(domain.getTotalScore()));
        userModelScore.setRtype(domain.getRType());
//        userModelScore.setAddScore(domain.getAddScore());
        userModelScore.setDeleted(Constants.UNDELETED);
//        userModelScore.setUserId(domain.getUserId());
//        userModelScore.setAiImageTotalScore(domain.getAiImageTotalScore());

        List<UserModelScore> list = lambdaQuery().eq(UserModelScore::getUserId, domain.getUserId()).eq(UserModelScore::getRtype, userModelScore.getRtype()).list();
        if (list.size() == 0) {

            baseMapper.insert(userModelScore);//添加
        } else {//有则修改
            lambdaUpdate().eq(UserModelScore::getRtype, userModelScore.getRtype()).eq(UserModelScore::getUserId, userModelScore.getUserId())
                    .set(UserModelScore::getTotalScore, userModelScore.getTotalScore())
                    .set(UserModelScore::getBaseScore, userModelScore.getBaseScore())
                    .set(UserModelScore::getRecordScore, userModelScore.getRecordScore())
                    .set(UserModelScore::getAddScore, userModelScore.getAddScore())
                    .set(UserModelScore::getAiImageTotalScore, userModelScore.getAiImageTotalScore())
                    .set(UserModelScore::getBaseRecordScore, userModelScore.getBaseRecordScore()).update();
        }


        // todo 更新记录表
        EmoHscoreLog emoHscoreLog = new EmoHscoreLog().setUserId(domain.getUserId()).setRtype(domain.getRType()).setScoreChanged(BigDecimal.valueOf(domain.getAddScore())).setModelScoreId(userModelScore.getId());
        emoHscoreLogService.save(emoHscoreLog);
    }

    @Override
    public void updateUserModelScoreList(UserModelScore item) {

        List<UserModelScore> list = lambdaQuery().eq(UserModelScore::getUserId, item.getUserId()).eq(UserModelScore::getRtype, item.getRtype()).list();
        if (ObjectUtil.isNull(list) || list.size() == 0) {
            baseMapper.insert(item);//添加
        } else {//有则修改
            lambdaUpdate().eq(UserModelScore::getRtype, item.getRtype()).eq(UserModelScore::getUserId, item.getUserId())
                    .set(UserModelScore::getTotalScore, item.getTotalScore())
                    .set(UserModelScore::getBaseScore, item.getBaseScore())
                    .set(UserModelScore::getRecordScore, item.getRecordScore())
                    .set(UserModelScore::getAddScore, item.getAddScore())
                    .set(UserModelScore::getAiImageTotalScore, item.getAiImageTotalScore()).update();
        }

    }


    @Override
    public void updateUserModelScoreByUserId(Long userId ) {

        List<RiskVO> riskVOList = null;
        R<List<RiskVO>> result = riskService.getRiskAll(SecurityConstants.INNER);
        if (StringUtils.isNotNull(result) && StringUtils.isNotNull(result.getData())) {
            riskVOList = result.getData();
        }

        Map<String, BigDecimal> riskTypeAndWeight = riskVOList.stream().collect(Collectors.toMap(RiskVO::getRtype, RiskVO::getWeight));


        Iterator<Map.Entry<String, BigDecimal>> iterator = riskTypeAndWeight.entrySet().iterator();


        Double ai = 0.0;
        Double advice = 0.0;
        Double appraise = 0.0;
        Double training = 0.0;
        Double survey = 0.0;
        Double total = 0.0;
        while (iterator.hasNext()) {
            Map.Entry<String, BigDecimal> entry = iterator.next();
            String riskType = entry.getKey();
            BigDecimal weight = entry.getValue();
            if (riskType.equals(HappyConstants.EMO_USER_RTYPE_AI)) {
                //算Ai的基礎分
                ai = getModelBaseScore(weight.doubleValue());
                Double modelRecordScore = getModelRecordScore(weight.doubleValue());
                saveUserModelScore(userId, HappyConstants.EMO_USER_RTYPE_AI, ai, modelRecordScore);

            }
            if (riskType.equals(HappyConstants.EMO_USER_RTYPE_ADVICE)) {
                //算的基礎分
                advice = getModelBaseScore(weight.doubleValue());
                Double modelRecordScore = getModelRecordScore(weight.doubleValue());
                saveUserModelScore(userId, HappyConstants.EMO_USER_RTYPE_ADVICE, advice, modelRecordScore);

            }
            if (riskType.equals(HappyConstants.EMO_USER_RTYPE_APPRAISE)) {
                appraise = getModelBaseScore(weight.doubleValue());
                Double modelRecordScore = getModelRecordScore(weight.doubleValue());
                saveUserModelScore(userId, HappyConstants.EMO_USER_RTYPE_APPRAISE, appraise, modelRecordScore);


            }
            if (riskType.equals(HappyConstants.EMO_USER_RTYPE_TRAINING)) {
                training = getModelBaseScore(weight.doubleValue());
                Double modelRecordScore = getModelRecordScore(weight.doubleValue());
                saveUserModelScore(userId,HappyConstants.EMO_USER_RTYPE_TRAINING, training, modelRecordScore);


            }
            if (riskType.equals(HappyConstants.EMO_USER_RTYPE_SURVEY)) {
                survey = getModelBaseScore(weight.doubleValue());
                Double modelRecordScore = getModelRecordScore(weight.doubleValue());
                saveUserModelScore(userId,HappyConstants.EMO_USER_RTYPE_SURVEY, survey, modelRecordScore);


            }

        }
        total = ai + advice + appraise + training + survey;//新用户就是基础分的总和
        //  直接算完基礎分直接改emo_user 的快乐分
        emoUserService.lambdaUpdate().set(User::getHappinessScore,total).update();


    }

    private void saveUserModelScore(Long userId, String rType, Double baseScore, Double recordScore) {
        UserModelScore userModelScore = new UserModelScore();
        userModelScore.setBaseScore(BigDecimal.valueOf(baseScore)).setBaseRecordScore(recordScore).setAddScore(0.0).setUserId(userId).setRtype(rType).setTotalScore(BigDecimal.valueOf(baseScore));
        save(userModelScore);
    }


    private Double getModelBaseScore(Double basePercent) {
        return (config.getMaxScore() * basePercent) * config.getModuleBaseScoreCoefficient();
    }

    private Double getModelRecordScore(Double basePercent) {
        return (config.getMaxScore() * basePercent) * config.getModuleRecordsCoefficient();
    }


}
